package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.converter.VocChapterConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.VocBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapterMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteChapterOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.VocChapterDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.VocChapterCommand;
import com.cskaoyan.wordmemorize.request.VocChapterPageRequest;
import com.cskaoyan.wordmemorize.service.VocBookService;
import com.cskaoyan.wordmemorize.service.VocChapterService;
import com.cskaoyan.wordmemorize.service.VocService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class VocChapterServiceImpl implements VocChapterService {

    @Autowired
    VocChapterMapper vocChapterMapper;

    @Autowired
    VocChapterConverter vocChapterConverter;

    @Autowired
    VocBookMapper vocBookMapper;

    @Autowired
    VocChapBookMapper vocChapBookMapper;

    @Autowired
    VocMapper vocMapper;

    @Autowired
    VocService vocService;

    @Override
    public PageDTO<VocChapterDTO> getChapterPage(VocChapterPageRequest pageQuery) {
        if (pageQuery.getPageNum() == null) {
            LambdaQueryWrapper<VocChapterDO> vocBookWrapper1 = new LambdaQueryWrapper<>();
            vocBookWrapper1.eq(pageQuery.getBookId()!=null,VocChapterDO::getBookId,pageQuery.getBookId());
            List<VocChapterDO> vocBookDOS = vocChapterMapper.selectList(vocBookWrapper1);

            return vocChapterConverter.vocChapterDOs2Page(vocBookDOS, (long) vocBookDOS.size());
        }

        Page<VocChapterDO> pageParam = new Page<>(pageQuery.getPageNum(), pageQuery.getCount());
        LambdaQueryWrapper<VocChapterDO> vocBookWrapper = new LambdaQueryWrapper<>();
        vocBookWrapper.eq(pageQuery.getBookId()!=null,VocChapterDO::getBookId,pageQuery.getBookId())
                .like(pageQuery.getKeyword() != null,VocChapterDO::getChapterName,pageQuery.getKeyword());
        Page<VocChapterDO> vocBookDOPage = vocChapterMapper.selectPage(pageParam, vocBookWrapper);

        return vocChapterConverter.vocChapterDOs2Page(vocBookDOPage.getRecords(),vocBookDOPage.getTotal());
    }

    @Override
    @OperateLog(dateType = "章节", operateType = OperateLogConstant.OPERATE_ADD)
    public void addChapter(VocChapterCommand command) {
        VocChapterDO vocChapterDO = vocChapterConverter.vocChapterCommand2DO(command);
        LambdaQueryWrapper<VocBookDO> vocBookDOWrapper = new LambdaQueryWrapper<>();
        vocBookDOWrapper.eq(VocBookDO::getId,vocChapterDO.getBookId());
        VocBookDO vocBookDO = vocBookMapper.selectOne(vocBookDOWrapper);
        if(vocBookDO.getChapterCount() != null){
            LambdaUpdateWrapper<VocBookDO> bookWrapper = new LambdaUpdateWrapper<>();
            bookWrapper.eq(VocBookDO::getId,vocBookDO.getId())
                    .setSql("chapter_count = chapter_count + 1");

            vocBookMapper.update(bookWrapper);
        }else{
            LambdaUpdateWrapper<VocBookDO> bookWrapper = new LambdaUpdateWrapper<>();
            bookWrapper.eq(VocBookDO::getId,vocBookDO.getId())
                    .setSql("chapter_count = 1");
            vocBookMapper.update(bookWrapper);
        }
        vocChapterMapper.insert(vocChapterDO);
    }

    @Override
    @OperateLog(dateType = "章节", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateChapter(VocChapterCommand command) {
        VocChapterDO vocChapterDO = vocChapterConverter.vocChapterCommand2DO(command);
        vocChapterMapper.updateById(vocChapterDO);
    }

    @Override
    @OperateLog(dateType = "章节", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteChapterOperateDTO deleteChapter(Long chapterId) {
        LambdaQueryWrapper<VocChapterDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VocChapterDO::getId,chapterId);
        VocChapterDO vocChapterDO = vocChapterMapper.selectOne(wrapper);
        deleteVocByVocChapterDO(vocChapterDO);
        DeleteChapterOperateDTO deleteChapterOperateDTO = vocChapterConverter.vocChapterDO2DeleteDTO(vocChapterDO);
        vocChapterMapper.deleteById(chapterId);
        return deleteChapterOperateDTO;
    }

    @Override
    @OperateLog(dateType = "章节", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    public List<DeleteChapterOperateDTO> deleteChapters(BatchDeleteCommand command) {
        List<Long> chapterIds = command.getIds().stream()
                .map(Long::parseLong)
                .collect(Collectors.toList());
        List<VocChapterDO> chapters = vocChapterMapper.selectBatchIds(chapterIds);
        List<DeleteChapterOperateDTO> resultList = new ArrayList<>();
        for (VocChapterDO vocChapterDO : chapters) {
            deleteVocByVocChapterDO(vocChapterDO);
            DeleteChapterOperateDTO deleteChapterOperateDTO = vocChapterConverter.vocChapterDO2DeleteDTO(vocChapterDO);
            resultList.add(deleteChapterOperateDTO);
            vocChapterMapper.deleteById(vocChapterDO.getId());
        }
        return resultList;
    }

    private void deleteVocByVocChapterDO(VocChapterDO vocChapterDO) {
        if(vocChapterDO.getBookId() != null){
            LambdaUpdateWrapper<VocBookDO> bookWrapper = new LambdaUpdateWrapper<>();
            bookWrapper.eq(VocBookDO::getId, vocChapterDO.getBookId())
                    .setSql("chapter_count = chapter_count - 1");
            vocBookMapper.update(bookWrapper);
        }
        if (vocChapterDO.getVocCount()!=0){
            LambdaQueryWrapper<VocChapBookDO> VocChapBookWrapper = new LambdaQueryWrapper<>();
            VocChapBookWrapper.eq(VocChapBookDO::getChapterId, vocChapterDO.getId());
            List<VocChapBookDO> vocChapBookDOS = vocChapBookMapper.selectList(VocChapBookWrapper);
            for (VocChapBookDO vocChapBookDO : vocChapBookDOS) {
                LambdaQueryWrapper<VocDO> vocDOWrapper = new LambdaQueryWrapper<>();
                vocDOWrapper.eq(VocDO::getId,vocChapBookDO.getVocId());
                VocDO vocDO = vocMapper.selectOne(vocDOWrapper);
                vocService.deleteVocabulary(vocDO.getId());
            }
        }
    }
}
